<template>
  <div class="app-container calendar-list-container">
    <el-container>
      <el-aside>
        <div class="tree-container">
          <span class="tree-title">组织结构概览</span>
          <el-tree
            @node-click="nodecheck"
            :data="data1"
            node-key="id"
            ref="tree"
            highlight-current
            :load="loadData"
            lazy
            :props="defaultProps">
          </el-tree>
        </div>
      </el-aside>
      <el-main>
          <!--条件查询-->
          <div class="filter-container">
            <el-input  style="width: 130px;" class="filter-item" v-model="query.name" :placeholder="'组织名称'">
            </el-input>
            <el-input  style="width: 130px;" class="filter-item" v-model="query.pid" :placeholder="'上级组织id'">
            </el-input>
            <el-button class="filter-item" style="margin-left: 10px;" type="primary" v-waves icon="el-icon-search" @click="getList">{{$t('table.search')}}</el-button>
            <el-button class="filter-item" style="margin-left: 10px;" @click="handleCreate" type="primary" icon="el-icon-edit">{{$t('table.add')}}</el-button>
            <el-button class="filter-item" type="primary" :loading="downloadLoading" v-waves icon="el-icon-download"  v-loading="downloadLoading" element-loading-text="正在下载中" @click="handleDownload">{{$t('table.export')}}</el-button>
            <el-button class="filter-item" style="margin-left: 10px;" @click="handleDelete" type="danger" icon="el-icon-delete">{{$t('table.delete')}}</el-button>
          </div>
          <!--带边框的表格-->
          <el-table
            :data="tableData"
            border
            v-loading="listLoading" element-loading-text="拼命加载中"
            @selection-change="handleSelectionChange"
            style="width: 100%">
            <!--展开显示详情-->
            <el-table-column
              type="expand">
              <template slot-scope="props">
                <el-form label-position="left" inline class="demo-table-expand">
                  <el-form-item label="组织id">
                    <span>{{ props.row.id }}</span>
                  </el-form-item>
                  <el-form-item label="组织名称">
                    <span>{{ props.row.name }}</span>
                  </el-form-item>
                  <el-form-item label="组织描述">
                    <span>{{ props.row.description }}</span>
                  </el-form-item>
                  <el-form-item label="上级组织id">
                    <span>{{ props.row.pid }}</span>
                  </el-form-item>
                  <el-form-item label="创建时间">
                    <!--时间戳转换-->
                    <span>{{props.row.ctime | parseTime('{y}-{m}-{d} {h}:{i}')}}</span>
                  </el-form-item>
                </el-form>
              </template>
            </el-table-column>
            <!--多选支持-->
            <el-table-column
            type="selection"
            >
            </el-table-column>
            <!--自定义索引-->
            <el-table-column
              type="index"
              label="序号"
              align="center"
              :index="indexMethod">
            </el-table-column>
            <!--<el-table-column-->
              <!--sortable-->
              <!--prop="id"-->
              <!--label="组织id"-->
            <!--&gt;-->
            <!--</el-table-column>-->
            <el-table-column
              sortable
              prop="name"
              label="组织名称"
            >
            </el-table-column>
            <el-table-column
              sortable
              prop="pid"
              label="上级组织id"
            >
            </el-table-column>
            <!--操作按钮-->
            <el-table-column align="center" :label="$t('table.actions')" width="230" class-name="small-padding fixed-width">
              <template slot-scope="scope">
                <!--编辑-->
                <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">{{$t('table.edit')}}</el-button>
              </template>
            </el-table-column>
          </el-table>

          <!--分页组件-->
          <div class="pagination-container">
            <el-pagination
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
              :current-page="current_page"
              :page-sizes="page_sizes"
              :page-size="page_size"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total_size">
            </el-pagination>
          </div>
          <!--添加修改组织-->
          <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
            <el-form :rules="rules" ref="info" :model="info" label-position="right" label-width="100px" style='width: 400px; margin-left:50px;'>
              <!--prop用于进行表单校验-->
              <el-form-item label="组织名称" prop="name">
                <el-input v-model="info.name"></el-input>
              </el-form-item>
              <el-form-item label="组织描述" prop="description">
                <el-input v-model="info.description"></el-input>
              </el-form-item>
              <el-form-item  v-if="this.dialogStatus === 'update' && !(this.info.oldPid == null)" label="旧的的上级组织id" prop="oldPid">
                <el-input :disabled="true" v-model="info.oldPid"></el-input>
              </el-form-item>
              <el-form-item  v-if="this.dialogStatus === 'create' || (this.dialogStatus === 'update' && this.info.oldPid == null)  " label="上级组织id" prop="pid">
                <el-input :disabled="true" v-model="info.pid"></el-input>
              </el-form-item>
              <el-form-item  v-if="this.dialogStatus === 'create'  " label="上级组织名称" prop="pidName">
                <el-input :disabled="true" v-model="info.pidName"></el-input>
              </el-form-item>
              <el-form-item  v-if="this.dialogStatus === 'update' && !(this.info.oldPid == null)" label="新的上级组织id" prop="pid">
                <el-input :disabled="true" v-model="info.pid"></el-input>
              </el-form-item>
              <el-form-item  v-if="this.dialogStatus === 'update' && !(this.info.oldPid == null)" label="新的上级组织名称" prop="pidName">
                <el-input :disabled="true" v-model="info.pidName"></el-input>
              </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
              <el-button @click="dialogFormVisible = false">{{$t('table.cancel')}}</el-button>
              <el-button v-if="dialogStatus=='create'" type="primary" @click="createData">{{$t('table.confirm')}}</el-button>
              <el-button v-else type="primary" @click="updateData">{{$t('table.confirm')}}</el-button>
            </div>
          </el-dialog>
      </el-main>
    </el-container>
  </div>
</template>


<script>
  import waves from '@/directive/waves' // 水波纹指令
  import { parseTime } from '@/utils'
  import { add, getByCondition, deleteByIds, updateSelectiveById } from '@/api/upms/organization'
  export default{
    directives: {
      waves
    },
    data() {
      return {
        data1: null,
        defaultProps: {
          children: 'children',
          label: 'name'
        },
        tableData: null, // 组织查询的数据
        current_page: 1,
        page_sizes: [5, 10, 15, 20, 50],
        page_size: 5,
        total_size: undefined,
        listLoading: false,
        status: [ // 描述状态
          0,
          1
        ],
        info: {
          id: undefined, // 用于添加组织
          name: undefined,
          pid: undefined,
          description: undefined,
          oldPid: undefined,
          pidName: undefined
        },
        query: { // 用于查询组织
          name: undefined,
          pid: undefined
        },
        dialogFormVisible: false, // 添加更新组织的会话窗口
        dialogStatus: undefined, // 会话的状态,是创建还是修改
        textMap: {
          update: '编辑组织',
          create: '添加组织'
        },
        downloadLoading: false,
        multipleSelection: [],
        rules: {
          name: [
            { required: true, message: '请输入组织名称', trigger: 'blur' }
          ],
          pid: [
            { required: true, message: '请输入上级组织id', trigger: 'blur' }
          ],
          description: [
            { required: true, message: '请输入组织描述', trigger: 'blur' }
          ]
        }
      }
    },
    methods: {
      deepClon(obj) { // 深度克隆对象
        const proto = Object.getPrototypeOf(obj)
        return Object.assign({}, Object.create(proto), obj)
      },
      indexMethod(index) { // 自定义序号
        return this.page_size * (this.current_page - 1) + index + 1
      },
      /**
       * 懒加载树的方法
       * @param node
       * @param resolve
       */
      loadData(node, resolve) {
        // 加载根节点
        if (node.level === 0) {
          const pojo = {}
          pojo.pid = 0
          getByCondition(pojo).then(response => {
            if (response.data.code === 0) {
              resolve(response.data.data.list)
            } else {
              this.$message({
                message: '加载组织结构失败,请稍后再试.',
                type: 'error'
              })
            }
          })
        }
        // 加载子节点
        if (node.level > 0) {
          const pojo = {}
          pojo.pid = node.data.id
          getByCondition(pojo, 1, 100, 'name_asc').then(response => {
            if (response.data.code === 0) {
              resolve(response.data.data.list)
            } else {
              this.$message({
                message: '加载组织结构失败,请稍后再试.',
                type: 'error'
              })
            }
          })
        }
      },
      handleCreate() {
        // 初始化数据
        for (var item in this.info) {
          this.info[item] = undefined
        }
        // 清除表单校验结果
        if (this.$refs['info']) {
          this.$refs['info'].clearValidate()
        }
        const checkedNode = this.$refs.tree.getCurrentNode()
        if (!(checkedNode == null)) {
          // 满足创建组织要求
          this.info.pid = checkedNode.id
          this.info.pidName = checkedNode.name
          this.dialogFormVisible = true
        } else {
          this.$message({
            message: '请在左侧组织结构概览选择上级节点',
            type: 'info'
          })
        }
        this.dialogStatus = 'create'
      },
      createData() {
        this.$refs.info.validate((validate) => {
          if (validate) {
            add(this.info).then(response => {
              if (response.data.code === 0) {
                // 左侧目录树添加节点
                // 获取父节点
                const node = this.$refs.tree.getNode(this.info.pid)
                if (node.loaded) {
                  let data = {}
                  // 添加子节点
                  data = this.deepClon(this.info)
                  data.id = response.data.data.id
                  this.$refs.tree.append(data, node)
                }
                this.dialogFormVisible = false
                this.$message({
                  message: '添加成功',
                  type: 'success'
                })
                this.getList()
              } else {
                this.$message({
                  message: '添加失败',
                  type: 'error'
                })
              }
            })
          }
        })
      },
      handleUpdate(value) { // 更新
        if (this.$refs['info']) {
          this.$refs['info'].clearValidate()
        }
        // 一定要深度克隆对象,不然容易出bug.比如先编辑然后添加
        this.info = this.deepClon(value)
        if (this.info.pid === 0) {
          // 如果是根节点则不允许更新上级组织
          this.info.oldPid = null
          this.dialogFormVisible = true
        } else {
          const checkedNode = this.$refs.tree.getCurrentNode()
          if (!(checkedNode == null)) {
            if (checkedNode.id === this.info.id) {
              this.$message({
                message: '误操作,不允许以自身为父节点,请重新选择.',
                type: 'info'
              })
              return
            }
            // 表示更新上级组织
            let temp = ''
            temp = this.info.pid
            this.info.pid = checkedNode.id
            this.info.oldPid = temp
            this.info.pidName = checkedNode.name
            this.dialogFormVisible = true
          } else {
            // 不更新上级节点
            this.info.oldPid = null
            this.dialogFormVisible = true
          }
        }
        this.dialogStatus = 'update'
      },
      updateData() {
        this.$refs['info'].validate((validate) => {
          if (validate) {
            // 更新数据
            updateSelectiveById(this.info).then(response => {
              if (response.data.code === 0) {
                this.dialogFormVisible = false
                this.$message({
                  message: '更新信息成功',
                  type: 'success'
                })
                if (this.info.oldPid == null) {
                  // 如果不更新上级组织
                  const node = this.$refs.tree.getNode(this.info.id)
                  node.data.name = this.info.name
                  node.data.description = this.info.description
                } else {
                  // 如果更新了上级组织
                  // 获取新的上级组织节点
                  const node = this.$refs.tree.getNode(this.info.pid)
                  this.$refs.tree.remove(this.info.id)
                  const data = {}
                  data.id = this.info.id
                  data.name = this.info.name
                  data.description = this.info.description
                  if (!(node == null)) {
                    if (node.loaded) {
                      // 父节点加载了子节点情况下才增加节点
                      this.$refs.tree.append(data, node)
                    }
                  }
                }
                this.getList()
              } else {
                this.$message({
                  message: '更新信息失败',
                  type: 'error'
                })
              }
            })
          } else {
            this.$message({
              message: '请按提示填入正确的表单信息',
              type: 'info'
            })
          }
        })
      },
      handleDelete() {
        if (this.multipleSelection.length < 1) {
          this.$message({
            message: '请在右侧选择要删除的信息',
            type: 'info'
          })
          return
        }
        this.$confirm('此操作将永久删除该信息, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          if (this.multipleSelection.length < 1) {
            this.$message({
              message: '请选择要删除的组织',
              type: 'info'
            })
          }
          // 传入数组
          const ids = []
          const data = this.multipleSelection
          data.forEach((item) => {
            ids.push(item.id)
          })
          this.deleteData(ids).then(response => {
            if (response.data.code === 0) {
              this.$message({
                type: 'success',
                message: '删除成功!'
              })
            } else {
              this.$message({
                type: 'error',
                message: '删除失败!'
              })
            }
          })
        })
      },
      deleteData(ids) {
        // 删除系统
        deleteByIds(ids).then(response => {
          if (response.data.code === 0) {
            this.$message({
              message: '删除成功',
              type: 'success'
            })
            // 删除左侧目录树的数据
            for (const item of ids) {
              this.$refs.tree.remove(item)
            }
            this.getList()
          } else {
            this.$message({
              message: '删除失败',
              type: 'error'
            })
          }
        })
      },
      getList() {
        this.listLoading = true
        // 加载列表
        getByCondition(this.query, this.current_page, this.page_size, 'pid_asc').then(response => {
          this.listLoading = false
          if (response.data.code === 0) {
            const data = response.data.data
            this.tableData = data.list
            this.total_size = data.total
          } else {
            this.$message({
              message: '加载信息失败',
              type: 'error'
            })
          }
        })
      },
      handleSizeChange(pageSize) {
        if (pageSize === this.page_size) {
          return
        }
        this.page_size = pageSize
        this.getList()
      },
      handleCurrentChange(pageNum) {
        if (pageNum === this.current_page) {
          return
        }
        this.current_page = pageNum
        this.getList()
      },
      handleSelectionChange(value) {
        this.multipleSelection = value
      },
      handleDownload() { // 导出当前页数据到excel
        if (this.multipleSelection.length < 1) {
          this.$message({
            message: '请在右侧选择要导出的信息',
            type: 'info'
          })
          return
        }
        this.downloadLoading = true
        import('@/vendor/Export2Excel').then(excel => {
          const tHeader = ['组织id', '组织名称', '组织描述', '创建时间', '上级组织id']
          const filterVal = ['id', 'name', 'description', 'ctime', 'pid']
          const data = this.formatJson(filterVal, this.multipleSelection)
          excel.export_json_to_excel(tHeader, data, 'upms-organization')
          this.downloadLoading = false
        })
      },
      formatJson(filterVal, jsonData) { // 格式化时间
        return jsonData.map(v => filterVal.map(j => {
          if (j === 'ctime') {
            return parseTime(v[j])
          } else {
            return v[j]
          }
        }))
      },
      /**
       * 节点点击事件的回调
       * @param data
       * @param node
       * @param component
       */
      nodecheck(data, node, component) {
        this.query.pid = data.id
      }
    },
    created() {
      this.getList()
    }
  }
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .tree-container{
    border: 1px dashed #85bbd2;
    border-radius: 2px;
    padding: 10px;
    text-align: center;
    min-height: 500px;
    .tree-title{
      display: inline-block;
      height: 40px;
      padding: 10px;
      color: #999999;
    }
  }
  .demo-table-expand {
    font-size: 0;
    label {
      width: 90px;
      color: #99a9bf;
    }
    .el-form-item {
      margin-right: 0;
      margin-bottom: 0;
      width: 50%;
    }
  }
</style>
